using System.Drawing.Printing;
using System.Reflection;

namespace ICP_MS.Plugin.HPLC;

internal class MultiPrintDocument : PrintDocument
{
	private PrintDocument[] _documents;

	private int _docIndex;

	private PrintEventArgs _args;

	public MultiPrintDocument(PrintDocument document1, PrintDocument document2)
	{
		_documents = new PrintDocument[2] { document1, document2 };
	}

	public MultiPrintDocument(PrintDocument[] documents)
	{
		_documents = documents;
	}

	protected override void OnBeginPrint(PrintEventArgs e)
	{
		base.OnBeginPrint(e);
		if (_documents.Length == 0)
		{
			e.Cancel = true;
		}
		if (!e.Cancel)
		{
			_args = e;
			_docIndex = 0;
			CallMethod(_documents[_docIndex], "OnBeginPrint", e);
		}
	}

	protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
	{
		e.PageSettings = _documents[_docIndex].DefaultPageSettings;
		CallMethod(_documents[_docIndex], "OnQueryPageSettings", e);
		base.OnQueryPageSettings(e);
	}

	protected override void OnPrintPage(PrintPageEventArgs e)
	{
		CallMethod(_documents[_docIndex], "OnPrintPage", e);
		base.OnPrintPage(e);
		if (e.Cancel || e.HasMorePages)
		{
			return;
		}
		CallMethod(_documents[_docIndex], "OnEndPrint", _args);
		if (!_args.Cancel)
		{
			_docIndex++;
			if (_docIndex < _documents.Length)
			{
				e.HasMorePages = true;
				CallMethod(_documents[_docIndex], "OnBeginPrint", _args);
			}
		}
	}

	private void CallMethod(PrintDocument document, string methodName, object args)
	{
		typeof(PrintDocument).InvokeMember(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, document, new object[1] { args });
	}

	public new void Dispose()
	{
		PrintDocument[] documents = _documents;
		foreach (PrintDocument document in documents)
		{
			document.Dispose();
		}
		base.Dispose();
	}
}
